perm filename HOSTS1.MID[NET,MRC]4 blob sn#357040 filedate 1978-05-19 generic text, type C, neo UTF8
COMMENT āŠ—   VALID 00015 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00003 00002	TITLE HOSTS1
C00006 00003	The source file of the table is HOSTS.TXT[NET,MRC].
C00008 00004	BOOT SAVER HSTTAB HSTTBE PDL
C00010 00005	DUMP
C00012 00006	UPPER UPPER1 UPPER2 UPPER3 UPPERS UPPER4
C00014 00007	CANON CNTLP CNTLP1 CNTLP2
C00017 00008	COUNT CONSNM CONSLP CONSCM CONSNX CONSLS
C00020 00009	MACH MACHL MACHNX
C00022 00010	MT MTLP NAMCPY MTE1
C00025 00011	SNT SNTL SNTWN
C00026 00012	MNAM MNAML MNAML1 MNAMF MNAMN MNAMX
C00029 00013	SNAM SNAML SNAMWN COMPAR POPJ1 CPOPJ
C00031 00014	WRITE DMPFN1 DMPFN2 DMPSNM
C00032 00015	OUTPT NAMP NAMEP NUMP $OUT UNAME $DATE TIME NAMPR NUMPR SYSNMS TIP PDP10 ITS TENEX TOPS10 TOPS20 TEN50 TWENEX BOTS10 SAIL PDP11 ELF UNIX RSX11 HYDRA MULTIC OUTEND
C00035 ENDMK
CāŠ—;
TITLE HOSTS1

; Adapted from MIT's HOSTS1 program written by Richard Stallman.

;This program .INSRTs the file HOSTS.TXT[NET,MRC] describing all the network hosts
;and produces a compiled file HOSTS1.BIN[NET,MRC] which network programs read in.

;The format of the compiled HOSTS1 file is:
HSTSID==0	; wd 0	SIXBIT /HOSTS1/
HSTFN1==1	; wd 1	SIXBIT /HOSTS/
HSTVRS==2	; wd 2	FN2 (version) of HOSTS file which this was compiled from.
		;	SIXBIT /SAIL/ if generated at SAIL
HSTWHO==3	; wd 3	UNAME of person who compiled this
HSTDAT==4	; wd 4	Date of compilation as sixbit YYMMDD
HSTTIM==5	; wd 5	Time of compilation as sixbit HHMMSS
NAMPTR==6	; wd 6	Address in file of NAME table.
NUMPTR==7	; wd 7	Address in file of NUMBER table.
		;....

;NUMBERS table:
; wd 0	Number of entries in this table.
; wd 1	Number of words per entry (currently 3).
; followed by entries, in order by host number.
; Each entry looks like this:
NUMNUM==0	;   entry wd 0	host number
NUMSYS==1	;   entry wd 1	lh  ptr to system name (ITS, TIP, TENEX, etc.)
		;			May be 0 => not known.
NUMNAM==1	;   entry wd 1  rh  ptr to official name of host.
NUMBTS==2	;   entry wd 2  lh  flags:
NUMSRV==400000	;	4.9 1 => server site.
NUMMCH==2	;   entry wd 2  rh  ptr to machine name (PDP10, etc).
		;			May be 0 => not known.
NUMLEN==3
;....

;NAMES table:
; wd 0	Number of entries
; followed by one word entries, sorted by the host name treated as a vector of
; signed integers, looking like:
		; lh		address in file of NUMBERS table entry for this host.
NAMNAM==0	; rh		ptr to host name
NAMLEN==1	;length of entry.

; Host, system and machine names are ASCIZ strings, all letters upper case.
; The strings are stored before, after and between the NAME and NUMBER tables.
;The source file of the table is HOSTS.TXT[NET,MRC].
;Each host is described by a line which looks like
; HOST	<official name>,<oct #>,<status>,<system>,<machine>,[<nickname list>]
;We assemble that into a string of entries, of this form:

HSTNAM==0	; wd 0	-> asciz host name
HSTNUM==1	; wd 1	host number
HSTSRV==2	; wd 2  nonzero iff server host
HSTSYS==3	; wd 3	-> asciz system name ("TIP" is a system name).
		;	    (may be 0).
HSTMCH==4	; wd 4  -> asciz machine name (may be 0).
HSTNIC==5	; wd 5	-> nickname list, a string of pointers to asciz
		;	    nicknames, terminated by a zero.
HSTLEN==6	;6 words per host entry.

DEFINE HOST NAME,NUM,STATUS,SYSTEM,MACHINE,NICKNAMES
	[ASCIZ /NAME/]
	NUM
	0+IFSE STATUS,SERVER,1
	IFSN SYSTEM,,  [ASCIZ "SYSTEM"]
	 .ELSE 0
	IFSN MACHINE,, [ASCIZ "MACHINE"]
	 .ELSE 0
	[ IRP NICK,,[NICKNAMES]
		[ASCIZ /NICK/]
	  TERMIN
	  0]
TERMIN
;BOOT SAVER HSTTAB HSTTBE PDL

;AC Defs

F==0
A=1
B=2
C=3
D=4
E=5
G=6
H=7
I=10
J=11
K=12
M=13
N=14
R=15
S=16
P=17

CALL=PUSHJ P,
RET=POPJ P,
SAVE=PUSH P,
REST=POP P,

LOC 140				;absolute assembly

;Running HOSTS1.DMP causes it to assemble and run a new version of HOSTS1.

BOOT:	MOVEI SAVER
	MOVEM JOBSA
	MOVEI SAVEND		;smallify to make small DMP file
	CORE
	 JFCL
	EXIT

SAVER:	PTWRS7 [0 ? [ASCIZ\Execute HOSTS1.MID[NET,MRC]/MIDAS/Compile
Save HOSTS1[NET,MRC]
Delete HOSTS1.REL
\]]
	EXIT

CONSTANTS

SAVEND==.-1

HSTTAB:	.INSRT HOSTS.TXT[NET,MRC]
HSTTBE:
NHOSTS==<.-HSTTAB>/HSTLEN	;NHOSTS IS NUMBER OF ENTRIES.

CONSTANTS			;PUT THE ASCIZ STRINGS HERE.


LPDL==40
PDL:	BLOCK LPDL+10
;DUMP

;Write out the compiled file.

DUMP:	MOVE P,[-LPDL,,PDL-1]
	GETPPN A,
	 JFCL
	HRLZM A,UNAME
	DATE B,
	IDIVI B,12.*31.
	ADDI B,64.
	IDIVI C,31.
	ADDI C,1
	ADDI D,1
	PUSH P,C
	IDIVI B,10.
	MOVEI A,'0(B)
	LSH A,6
	ADDI A,'0(C)
	POP P,B
	IDIVI B,10.
	LSH A,6
	ADDI A,'0(B)
	LSH A,6
	ADDI A,'0(C)
	IDIVI D,10.
	LSH A,6
	ADDI A,'0(D)
	LSH A,6
	ADDI A,'0(E)
	MOVEM A,$DATE
	MSTIME B,
	IDIVI B,1000.
	IDIVI B,60.*60.
	IDIVI C,60.
	PUSH P,C
	IDIVI B,10.
	MOVEI A,'0(B)
	LSH A,6
	ADDI A,'0(C)
	POP P,B
	IDIVI B,10.
	LSH A,6
	ADDI A,'0(B)
	LSH A,6
	ADDI A,'0(C)
	IDIVI D,10.
	LSH A,6
	ADDI A,'0(D)
	LSH A,6
	ADDI A,'0(E)
	MOVEM A,TIME
;	JRST UPPER
;UPPER UPPER1 UPPER2 UPPER3 UPPERS UPPER4

;Now convert all system, machine and host names to upper case.
;This is so that user programs can search and compare more easily.
;Also, it makes sure that CANON really maps all instances of a system
;or machine name into the same name.

UPPER:	MOVEI A,HSTTAB
UPPER1:	MOVE B,HSTSYS(A)
	CALL UPPERS
	MOVE B,HSTMCH(A)
	CALL UPPERS
	MOVE B,HSTNAM(A)
	CALL UPPERS
	MOVE C,HSTNIC(A)	;Get address of nickname list,
UPPER2:	SKIPN B,(C)
	 JRST UPPER3
	CALL UPPERS		;and convert each nickname in it.
	AOJA C,UPPER2

UPPER3:	ADDI A,HSTLEN		;Advance to next host.
	CAIE A,HSTTBE
	 JRST UPPER1
	JRST CANON

;Convert the the ASCIZ string that B points to to upper case,
;modifying it in place.  Clobbers B and E.

UPPERS:	HRLI B,440700
UPPER4:	ILDB E,B
	JUMPE E,CPOPJ
	CAIL E,"a
	 CAILE E,"z
	  JRST UPPER4
	SUBI E,"a-"A
	DPB E,B
	JRST UPPER4
;CANON CNTLP CNTLP1 CNTLP2

;Now store the System name strings into the file, storing each
;distinct name only once.  We replace each System name pointer
;with a pointer (in our address space) to the string stored
;into the file (the "interned" string) so we don't have to search
;the file when we write the NAMES table.
;Also, G counts how many words of space will be needed for all
;the host names and nicknames.

CANON:	MOVEI A,SYSNMS		;A is storing pointer for new system names.
	MOVEI B,HSTTAB		;B points at data of next host to hack.
	SETZB G,H
CNTLP:	SKIPE C,HSTSYS(B)	;Store the system name if necessary.
	 CALL CONSNM
	SKIPE HSTSYS(B)
	 MOVEM J,HSTSYS(B)	;replace system name string with interned one.
	SKIPE C,HSTMCH(B)
	 CALL CONSNM		;Do the same thing with the machine name.
	SKIPE HSTMCH(B)
	 MOVEM J,HSTMCH(B)
	MOVE C,HSTNAM(B)
	CALL COUNT		;Count space official name will take,
	MOVE D,HSTNIC(B)
CNTLP1:	SKIPN C,(D)		;and space the nicknames will take.
	 AOJA H,CNTLP2
	CALL COUNT
	AOS H			;H counts number of names and nicknames.
	AOJA D,CNTLP1

CNTLP2:	ADDI B,HSTLEN
	CAIGE B,HSTTBE
	 JRST CNTLP
	ADD G,OUTPT		;Leave space after system names for them
	MOVEM G,NUMP		;to find where NUMBERS table should start.
	MOVEI M,NHOSTS
	MOVEM M,(G)		;Store number of entries in NUMBERS table.
	MOVEI A,NUMLEN
	MOVEM A,1(G)		;Store number of words per entry.
	IMUL M,A		;Compute total length
	ADDI M,2(G)		;and thus the position of NAMES table.
	MOVEM M,NAMEP
	MOVEM M,NAMP
	MOVEM H,@NAMEP		;Store size of NAMES table (= # of hosts + nicknames)
	AOS NAMEP		;in its 1st word, and advance storing pointer.
	SUBI G,$OUT
	MOVEM G,NUMPR
	SUBI M,$OUT
	MOVEM M,NAMPR
	JRST MACH		;Go figure out machine names if possible.
;COUNT CONSNM CONSLP CONSCM CONSNX CONSLS

;C -> an ASCIZ string.  Add to G the number of words it occupies.
;Clobbers E.

COUNT:	MOVE E,(C)
	AOS G
	TRNN E,376
	 RET
	AOJA C,COUNT

;C -> an ASCIZ string;  intern it in the system names table.
;If the table has no string EQUAL to the arg, make a new one at the end.
;In either case, return in J the address of the interned string.
;A -> the beginning of the system names table, and OUTPT -> the end.
;Clobbers D, E, and K.

CONSNM:	MOVE E,A		;E looks at all strings in table, 1 by 1.
CONSLP:	MOVE J,E
	CAMN E,OUTPT		;Reached start of next string in table
	 JRST CONSLS		; but maybe it's the end of table.
	MOVE K,C
CONSCM:	MOVE D,(K)
	CAME D,(E)		;Compare table string agains our arg word
	 JRST CONSNX		;by word.  No match => skip to next string
	TRNN D,376		;in table.  Match until end of ASCIZ =>
	 RET			;we found the arg in the table.
	AOS E			;else compare next words of the two strings.
	AOJA K,CONSCM
	
CONSNX:	MOVE K,(E)		;Advance to start of next ASCIZ string in table
	TRNN K,376
	 AOJA E,CONSLP		;then compare it against our arg.
	AOJA E,CONSNX

CONSLS:	MOVE D,(C)		;String not found in table, so copy it
	MOVEM D,@OUTPT		;to the end of the table.
	AOS OUTPT
	TRNE D,376
	 AOJA C,CONSLS
	RET
;MACH MACHL MACHNX

;Now figure out the type of machine from the system name, if possible,
;in case HOSTS currently has no info on machine type.

MACH:	MOVEI A,HSTTAB
MACHL:	MOVE B,HSTSYS(A)
	CAIE B,TEN50
	 CAIN B,TOPS10
	  MOVEI B,BOTS10	;Canonicalize system name.
	CAIN B,TOPS20
	 MOVEI B,TWENEX
	MOVEM B,HSTSYS(A)
	SKIPE C,HSTMCH(A)	;If machine type not already known,
	 JRST MACHNX		;try to determine it from system name.
	CAIE B,ITS
	 CAIN B,TENEX
	  MOVEI C,PDP10
	CAIE B,TOPS10
	 CAIN B,TOPS20
	  MOVEI C,PDP10
	CAIE B,SAIL
	 CAIN B,TEN50
	  MOVEI C,PDP10
	CAIE B,BOTS10
	 CAIN B,TWENEX
	  MOVEI C,PDP10
	CAIN B,TIP
	 MOVEI C,TIP
	CAIN B,MULTIC
	 MOVEI C,MULTIC
	CAIE B,HYDRA
	 CAIN B,RSX11
	  MOVEI C,PDP11
	CAIE B,ELF
	 CAIN B,UNIX
	  MOVEI C,PDP11
	MOVEM C,HSTMCH(A)
MACHNX:	ADDI A,HSTLEN
	CAIE A,HSTTBE
	 JRST MACHL
;	JRST MT			;After this, build the NAMES table.
;MT MTLP NAMCPY MTE1

;Now build the contents of the NUMBERS table, exact but not sorted.

MT:	MOVEI B,HSTTAB		;B points at data of next host to hack.
	MOVE A,NUMP
	ADDI A,2		;A is pointer for storing NUMBERS table entries.
MTLP:	MOVE C,HSTNAM(B)
	MOVE E,HSTNUM(B)
	MOVEM E,NUMNUM(A)	;Store the host number.
	SKIPE E,HSTSYS(B)
	 SUBI E,$OUT		;Store ptr to system name (in file addr space).
	HRLZM E,NUMSYS(A)
	SKIPE E,HSTMCH(B)
	 SUBI E,$OUT
	MOVEM E,NUMMCH(A)	;and the machine name.
	MOVSI E,NUMSRV
	SKIPE HSTSRV(B)		;If a server host, set the flag for that.
	 IORM E,NUMBTS(A)
	CALL NAMCPY		;Copy the host name to where OUTPT points,
	HRRM E,NUMNAM(A)	;and store a pointer to the copy.
	ADDI A,NUMLEN		;Advance A to store next entry next time.
	ADDI B,HSTLEN
	CAIGE B,HSTTBE
	 JRST MTLP
	CAME A,NAMP		;Check that NUMBERS occupies expected
	 JRST 4,.-1		;amount of space.
	SUB A,NUMP
	SUBI A,2
	MOVE B,@NUMP		;Check that right number of NUMBERS
	IMULI B,NUMLEN		;entries were made.
	CAME A,B
	 JRST 4,.-1
	JRST SNT

;Copy ASCIZ string <- C to where OUTPT points, advancing OUTPT.
;Return in E the address of the copy, in file address space.

NAMCPY:	MOVE E,OUTPT
	SUBI E,$OUT
	SAVE E
MTE1:	MOVE E,(C)
	MOVEM E,@OUTPT
	AOS OUTPT
	TRNE E,376
	 AOJA C,MTE1
	REST E
	RET
;SNT SNTL SNTWN

;Now sort the NUMBERS table by numbers.

SNT:	SETZ B,			;Another pass, no exchanges yet.
	MOVE A,NUMP
	ADDI A,2
SNTL:	MOVE C,NUMNUM(A)
	CAMG C,NUMNUM+NUMLEN(A)	;Skip if this entry and next are mis-ordered.
	 JRST SNTWN		;No skip => this one's is less.
	SETO B,			;Wrong order => interchange.
REPEAT 3,[
	MOVE C,.RPCNT(A)
	EXCH C,.RPCNT+NUMLEN(A)
	MOVEM C,.RPCNT(A)
]
SNTWN:	ADDI A,NUMLEN		;Keep exchanging if nec thru all of NUMBERS.
	MOVEI C,NUMLEN(A)
	CAME C,NAMP
	 JRST SNTL
	JUMPN B,SNT		;If not finished exchanging, need another pass.
	JRST MNAM		;Now NUMBERS is finished, so make NAMES.
;MNAM MNAML MNAML1 MNAMF MNAMN MNAMX

;Now that the NUMBERS table is finished, we can make the NAMES
;table, which has pointers into the NUMBERS table.

MNAM:	MOVE A,NUMP		;A scans through the NUMBERS table.
	ADDI A,2
	MOVE B,@NUMP
MNAML:	MOVEI C,HSTTAB		;Make the NAMES table entries for the next host.
	MOVE D,NUMNUM(A)
MNAML1:	CAMN D,HSTNUM(C)	;Find the HSTTAB entry for this host, since it
	 JRST MNAMF		;has the nicknames in it.
	ADDI C,HSTLEN
	CAIE C,HSTTBE
	 JRST MNAML1
	JRST 4,.-1

MNAMF:	HRLZI E,-$OUT(A)	;Make the official name's entry.  Get NUMBERS entry addr in lh.
	HRR E,NUMNAM(A)		;Put ptr to host name in rh (copy from NUMBERS entry).
	MOVEM E,@NAMEP
	AOS NAMEP
	MOVE D,HSTNIC(C)	;D points to list of nickname pointers.
MNAMN:	SKIPN C,(D)		;C gets the next nickname.
	 JRST MNAMX
	CALL NAMCPY		;Copy the nickname into file, E gets addr of copy.
	HRLI E,-$OUT(A)		; Get NUMBERS entry addr in lh.
	MOVEM E,@NAMEP
	AOS NAMEP
	AOJA D,MNAMN	

MNAMX:	ADDI A,NUMLEN		;Finished making NAMES entry for this host.  Hack the next.
	SOJG B,MNAML
	MOVE B,NAMEP		;Check that expected number of NAMES
	SUB B,NAMP		;entries were made.
	SUBI B,1
	CAME B,@NAMP
	 JRST 4,.-1
	MOVE B,OUTPT		;Check that host names exactly filled
	CAME B,NUMP		;the space allotted.
	 JRST 4,.-1
	JRST SNAM		;Now go sort this table.
;SNAM SNAML SNAMWN COMPAR POPJ1 CPOPJ

;Sort the NAMES table.

SNAM:	SETZ B,			;No exchanges yet this pass.
	MOVE A,NAMP		;A is pointer for scanning through.
	ADDI A,1
	MOVE G,NAMEP		;G -> next to the last NAMES entry.
	SUBI G,2
SNAML:	HRRZ C,NAMNAM(A)	;Get this entry's name and next entry's.
	HRRZ D,NAMNAM+NAMLEN(A)
	ADDI C,$OUT		;Convert file's address space to ours.
	ADDI D,$OUT
	CALL COMPAR		;Skip if these two entries mis-ordered.
	 JRST SNAMWN
	SETO B,
	MOVE E,(A)
	EXCH E,NAMLEN(A)
	MOVEM E,(A)
SNAMWN:	CAME A,G		;Each pass scan whole table.
	 AOJA A,SNAML		;If we exchanged, we need another pass.
	JUMPN B,SNAM
	JRST WRITE

;Compare two ASCIZ strings as vectors of signed integers.
;C -> first string, D -> second.  Skip if first is greater.
;If the strings are EQUAL, we HALT.

COMPAR:	MOVE E,(C)
	CAMGE E,(D)
	 RET
	CAMLE E,(D)
	 JRST POPJ1
	TRNN E,376		;Two host names are EQUAL???
	 JRST 4,.-1
	AOS C
	AOJA D,COMPAR

POPJ1:	AOS (P)
CPOPJ:	RET
;WRITE DMPFN1 DMPFN2 DMPSNM

;Now write out the compiled hosts file.

WRITE:	OPEN [17 ? 'DSK,, ? 0]
	 JRST 4,.-1
	ENTER DMPFN1
	 JRST 4,.-1
	MOVE B,NAMEP
	SUBI B,$OUT+1		;and size of file.
	HRLO A,B
	EQVI A,$OUT-1
	SETZ B,
	OUT A
	 CAIA
	  JRST 4,.-1
	CLOSE			;write and close
	JRST BOOT		;now save ourselves for next time

;These are the filenames to write.

DMPFN1:	SIXBIT /HOSTS1/
DMPFN2:	SIXBIT /BIN/
	0
DMPSNM:	SIXBIT /NETMRC/
;OUTPT NAMP NAMEP NUMP $OUT UNAME $DATE TIME NAMPR NUMPR SYSNMS TIP PDP10 ITS TENEX TOPS10 TOPS20 TEN50 TWENEX BOTS10 SAIL PDP11 ELF UNIX RSX11 HYDRA MULTIC OUTEND

;Here is the beginning of the hosts table file.

OUTPT:	OUTEND			;Pointer to where to put next word we add.
NAMP:	0			;Addr of place to put NAME table
				;(in our address space).
NAMEP:	0			;Ptr for storing into NUMBERS table.

NUMP:	0			;Addr of place to put NUMBER table.

CONSTANTS
VARIABLES

;The data actually written into the file starts here.

$OUT:	SIXBIT /HOSTS1/
	.IFNM1			;Include filenames of HOSTS file.
IFN .IFNM2-SIXBIT/TXT/,.IFNM2
.ELSE	SIXBIT/SAIL/
UNAME:	0			;UNAME of person who compiles the file.
$DATE:	0			;Date and time of compilation.
TIME:	0
NAMPR:	0			;Pointer to NAME table, rel to $OUT.
NUMPR:	0			;Pointer to NUMBER tables, rel to $OUT.
SYSNMS:				;The table of interned system and machine
				;names starts here.
TIP:	ASCIZ /TIP/		;These are pre-interned so they go in known
PDP10:	ASCIZ /PDP10/		;places and are easy to test for in MACH.
ITS:	ASCIZ /ITS/		;Note: PDP10, not PDP-10, so fits in 1 word.
TENEX:	ASCIZ /TENEX/
TOPS10:	ASCIZ /TOPS-10/
TOPS20:	ASCIZ /TOPS-20/
TEN50:	ASCIZ /10-50/
TWENEX:	ASCIZ /TWENEX/
BOTS10:	ASCIZ /BOTTOMS-10/
SAIL:	ASCIZ /WAITS/
PDP11:	ASCIZ /PDP11/
ELF:	ASCIZ /ELF/
UNIX:	ASCIZ /UNIX/
RSX11:	ASCIZ /RSX-11/
HYDRA:	ASCIZ /HYDRA/
MULTIC:	ASCIZ /MULTICS/

OUTEND:	BLOCK 20*2000
	-1
FOO==.
CONSTANTS
VARIABLES
IFN .-FOO,Constants or variables in skeleton output file

END DUMP